<?php
if(! extension_loaded('sockets')){
	die('The sockets extension is not loaded');
}

//确保在链接客户端时不会超时
set_time_limit(0);
//设置ip和端口号
$address="127.0.0.1";
$port = "2046";

/** 
 * 创建一个SOCKET  
 * AF_INET=是ipv4 如果用ipv6，则参数为 AF_INET6 
 * SOCK_STREAM为socket的tcp类型，如果是UDP则使用SOCK_DGRAM 
*/  
$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP) or die("socket_create() 失败的原因是:" . socket_strerror(socket_last_error()) . "/n");
//阻塞模式
socket_set_block($sock) or die("socket_set_block 失败的原因是:".socket_strerror(socket_last_error())."\n"); 
//绑定到socket端口
$result = socket_bind($sock,$address,$port) or die("socket_bind() 失败的原因是:" . socket_strerror(socket_last_error()) . "/n");

//开始监听
$result = socket_listen($sock,4) or die("socket_listen() 失败的原因是:" . socket_strerror(socket_last_error()) . "/n");  
echo "OK\nBinding the socket on $address:$port ... ";  
echo "OK\nNow ready to accept connections.\nListening on the socket ... \n"; 
while( true ){// never stop the daemon
	//它接收连接请求，并调用一个子链接socket来处理客户端和服务器间的信息
	$msgsock = socket_accept($sock)  or  die("socket_accept() failed: reason: " . socket_strerror(socket_last_error()) . "/n");
	//读取客户端数据  
    echo "Read client data \n";  
    //socket_read函数会一直读取客户端数据,直到遇见\n,\t或者\0字符.PHP脚本把这写字符看做是输入的结束符. 
    $buf = socket_read($msgsock, 8192);
    echo "Received msg: $buf   \n";

    //数据传送，向客户端写入返回结果
    $msg = "welcome \n";
    socket_write($msgsock, $msg,strlen($msg)) or die("socket_write() failed: reason: " . socket_strerror(socket_last_error()) ."/n");
    //一旦输出被返回到客户端,父/子socket都应通过socket_close($msgsock)函数来终止  
    socket_close($msgsock);  
}
socket_close($sock);
exit();


// create unix udp socket
$socket = socket_create(AF_UNIX, SOCK_DGRAM, 0);
if( !$socket){
	die('Unable to create AF_UNIX socket');
}

//same socket will be used in recv_from and send_to
$server_side_sock = dirname(__FILE__)."/server.sock";
if(!socket_bind($socket,$server_side_sock)){
	die("Unable to bind to $server_side_sock");
}

while( true ){//server nerver exits
	//receive query
	if(!socket_set_block($socket)){
		die('Unable to set blocking mode for socket');
	}

	$buf = '';
	$from = '';
	echo "Ready to receive ...\n";
	// will block to wait client query
	$bytes_received = socket_recvfrom($socket, $buf, 65536, 0, $from);

	if ($bytes_received == -1)
        die('An error occured while receiving from the socket');
	echo "Received $buf from $from\n";

	$buf .= "->Response"; // process client query here

	// send response
	if (!socket_set_nonblock($socket))
	        die('Unable to set nonblocking mode for socket');
	// client side socket filename is known from client request: $from
	$len = strlen($buf);
	$bytes_sent = socket_sendto($socket, $buf, $len, 0, $from);
	if ($bytes_sent == -1)
	        die('An error occured while sending to the socket');
	else if ($bytes_sent != $len)
	        die($bytes_sent . ' bytes have been sent instead of the ' . $len . ' bytes expected');
	echo "Request processed\n";
}